package com.atguigu.day26.work;

import org.junit.Test;

import java.lang.reflect.*;
import java.util.Arrays;

public class Work1 {
    /*用反射获取AtguiguDemo类的Class对象，
    并获取它的所有信息，
    包括类加载器、包名、类名、父类、父接口、属性、构造器、方法们等
    */
    @Test
    public void w1() throws ClassNotFoundException {
        Class clazz=Class.forName("com.atguigu.day26.work.AtguiguDemo");//获取class对象

        ClassLoader classLoader = clazz.getClassLoader();//类加载器
        System.out.println("类加载器"+classLoader);

        Package pkg=clazz.getPackage();//用于返回在ClassLoader中定义的包或在ClassLoader祖先中定义的包
        System.out.println("包名:"+pkg.getName());

        int cMod=clazz.getModifiers();//返回int类型值表示该字段的修饰符
        System.out.println("类的修饰符"+ Modifier.toString(cMod));

        System.out.println("类名"+clazz.getName());
        System.out.println("父类"+clazz.getSuperclass().getName());
        Class[] interfaces=clazz.getInterfaces();
        System.out.println("父接口们:"+ Arrays.toString(interfaces));

        Field[] declareFields=clazz.getDeclaredFields();//获得某个类的所有声明的字段，即包括public、private和proteced，但是不包括父类的申明字段
        for (int i = 0; i < declareFields.length; i++) {
            System.out.println("第"+(i+1)+"个字段:");
            int fMod=declareFields[i].getModifiers();
            System.out.println("修饰符:"+Modifier.toString(fMod));
            System.out.println("数据类型:"+declareFields[i].getType().getName());
            System.out.println("属性名:"+declareFields[i].getName());
        }
        Constructor[] declaredConstructors=clazz.getDeclaredConstructors();//用于返回一个Constructor对象数组，该数组指示此Class对象所表示的类定义的构造函数的类型
        for (int i = 0; i < declaredConstructors.length; i++) {
            System.out.println("第" + (i+1) + "个构造器：");
            int csMod=declaredConstructors[i].getModifiers();
            System.out.println("修饰符"+Modifier.toString(csMod));
            System.out.println("构造器名"+declaredConstructors);
            System.out.println("形参列表"+Arrays.toString(declaredConstructors[i].getParameterTypes()));
        }
        Method[] declaredMethods=clazz.getDeclaredMethods();//获取本类中的所有方法，包括私有的(private、protected、默认以及public)的方法
        for (int i = 0; i < declaredMethods.length; i++) {
            System.out.println("第" + (i+1) + "个成员方法：");
            int csMod=declaredMethods[i].getModifiers();
            System.out.println("修饰符:"+Modifier.toString(csMod));
            System.out.println("返回值类型:"+declaredMethods[i].getReturnType().getName());
            System.out.println("方法名:"+declaredMethods[i].getName());
            System.out.println("形参列表:"+Arrays.toString(declaredMethods[i].getParameterTypes()));
        }
    }
    /*用反射获取school的值，
    并修改school的值为“尚硅谷大学”，
    然后再获取school的值
    */
    @Test
    public void w2() throws Exception{
        Class clazz=Class.forName("com.atguigu.day26.work.AtguiguDemo");
        Field field=clazz.getDeclaredField("school");
        field.setAccessible(true);
        Object value=field.get(null);
        System.out.println("school="+value);

        field.set(null,"尚硅谷大学");
        value=field.get(null);
        System.out.println("school="+value);
    }
    /*用反射创建AtguiguDemo类的对象，
    并设置班级名称className属性的值，
    并获取它的值
    */
    @Test
    public void w3() throws IllegalAccessException, NoSuchFieldException, InstantiationException, ClassNotFoundException {
        Class clazz=Class.forName("com.atguigu.day26.work.AtguiguDemo");
        Object object=clazz.newInstance();
        Field field=clazz.getDeclaredField("className");
        field.setAccessible(true);
        Object value=field.get(object);
        System.out.println("className="+value);
        field.set(object,"211018班");
        value=field.get(object);
        System.out.println("className="+value);
    }
    /*用反射获取有参构造创建2个AtguiguDemo类的对象，
    并获取compareTo方法，
    调用compareTo方法，
    比较大小
    */
    @Test
    public void w4() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException, ClassNotFoundException {
        Class clazz=Class.forName("com.atguigu.day26.work.AtguiguDemo");
        Constructor c=clazz.getDeclaredConstructor(String.class);
        Object o1=c.newInstance("11111班");
        Object o2=c.newInstance("22222班");
        Method method=clazz.getDeclaredMethod("compareTo", Object.class);
        System.out.println("o1与o2比较结果:"+ method.invoke(o1,o2));

    }
}
